<!DOCTYPE html>

<html lang="en">
  <head>
    
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    
    <title>依赖注入与服务定位器（Dependency Injection/Service Location） &mdash; Phalcon 3.0.1 文档</title>
    <meta name="keywords" content="php, phalcon, phalcon php, php framework, faster php framework">
    <link rel="stylesheet" type="text/css" href="http://cdn.staticfile.org/twitter-bootstrap/3.3.6/css/bootstrap.min.css" />
    <link rel="stylesheet" type="text/css" href="/www/css/phalcon.min.css" />
    <link href='//fonts.googleapis.com/css?family=Open+Sans:700,400' rel='stylesheet' type='text/css'>
    <link href="//fonts.googleapis.com/css?family=Merriweather:400,700" rel="stylesheet" type="text/css" />
    <!--
    EUROPE <link href='//fonts.googleapis.com/css?family=Open+Sans:700,400&subset=latin-ext' rel='stylesheet' type='text/css'>
    GREEK <link href='//fonts.googleapis.com/css?family=Open+Sans:700,400&subset=greek-ext' rel='stylesheet' type='text/css'>
    RUSSIA <link href='//fonts.googleapis.com/css?family=Open+Sans:700,400&subset=cyrillic-ext,latin' rel='stylesheet' type='text/css'>
    -->

    <!-- HTML5 shim and Respond.js IE8 support of HTML5 elements and media queries -->
    <!--[if lt IE 9]>
      <script src="https://oss.maxcdn.com/libs/html5shiv/3.7.0/html5shiv.js"></script>
      <script src="https://oss.maxcdn.com/libs/respond.js/1.4.2/respond.min.js"></script>
    <![endif]-->

    <link rel="stylesheet" href="../static/pygments.css" type="text/css" />
    <link rel="stylesheet" href="../static/docs.css" type="text/css" />
    <script type="text/javascript">
      var DOCUMENTATION_OPTIONS = {
        URL_ROOT:    '../',
        VERSION:     '3.0.1',
        COLLAPSE_MODINDEX: false,
        FILE_SUFFIX: '.html',
        HAS_SOURCE:  true
      };
    </script>

    <script src="http://cdn.staticfile.org/jquery/1.8.1/jquery.min.js"></script>
    <script type="text/javascript" src="../static/docs.js"></script>
    <link rel="shortcut icon" href="../static/favicon.ico"/>
    <link rel="top" title="Phalcon 3.0.1 文档" href="../index.html" />
    <link rel="next" title="MVC 架构（The MVC Architecture）" href="mvc.html" />
    <link rel="prev" title="示例列表（List of examples）" href="samples.html" /> 
  </head>
  <body>

<header class="page-header">
    <nav class="navbar" role="navigation">
        <div class="container">
            <div class="navbar-header">
                <button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#main-menu-container">
                    <span class="sr-only">Toggle navigation</span><span class="icon-bar"></span><span class="icon-bar"></span><span class="icon-bar"></span>
                </button>
                <a class="navbar-brand phalcon-logo" href="/"><span itemprop="name" class="sr-only">Phalcon PHP</span></a>
            </div>

            <div class="collapse navbar-collapse navbar-right" id="main-menu-container">
                <ul class="nav navbar-nav main-menu">
                  <li class="first"><a href="//phalconphp.com/en/download" class="header-nav-link">Download</a></li>
                  <li><a href="//docs.phalconphp.com/en/latest/index.html" class="header-nav-link" target="_blank">Documentation</a></li>
                  <li><a href="//forum.phalconphp.com/" class="header-nav-link" target="_blank">Forum</a></li>
                  <li><a href="//blog.phalconphp.com/" class="header-nav-link" target="_blank">Blog</a></li>
                  <li><a href="//phalconist.com/" class="header-nav-link" target="_blank">Resources</a></li>
                  <li><a href="//phalconphp.com/en/about">About</a></li>
                  <li><div align="right">
                      <iframe src="https://ghbtns.com/github-btn.html?user=phalcon&amp;repo=cphalcon&amp;type=watch&amp;count=true&amp;size=large"
      allowtransparency="true" frameborder="0" scrolling="0" width="152px" height="30px"></iframe>
                    </div></li>
                </ul>
            </div>
        </div>
    </nav>
  </header>

<div class="heading">
    <div class="container">
        <div class="row">
            <h2>Documentation</h2>
        </div>
    </div>
</div>
    <div class="related">
      <ul>
        <li class="right" >
          <a href="../genindex.html" title="总目录"
             accesskey="I">索引</a></li>
        <li class="right" >
          <a href="mvc.html" title="MVC 架构（The MVC Architecture）"
             accesskey="N">下一页</a> |</li>
        <li class="right" >
          <a href="samples.html" title="示例列表（List of examples）"
             accesskey="P">上一页</a> |</li>
        <li><a href="//phalconphp.com">Home</a> &raquo;</li>
        <li><a href="../index.html">Phalcon 3.0.1 文档</a> &raquo;</li> 
      </ul>
    </div>  

      <table width="100%" align="center" cellpadding="0" cellspacing="0">
        <tr>
      <td class="primary-box" width="25%" valign="top">
            <div>
            <div id="searchbox" style="">
                <!--<form class="search" action="http://readthedocs.org/search/project/" method="get">
                  <input type="search" name="q" size="25" placeholder="Search">
                  <input type="submit" value="Go">
                  <input type="hidden" name="selected_facets" value="project:">
                </form>-->
                <div style="width:200px;padding:10px">
                  <gcse:searchbox-only></gcse:searchbox-only>
                </div>
            </div>
            </div>
            <div style="padding:5px;padding-left:10px">
              <div id="carbonads-container">
                <div class="carbonad"><div id="azcarbon"></div>
                <script async type="text/javascript" src="//cdn.carbonads.com/carbon.js?zoneid=1673&serve=C6AILKT&placement=phalconphpcom" id="_carbonads_js"></script>
                </div></div>
            </div>
            <h3><a href="../index.html">內容目录</a></h3>
            <ul>
<li><a class="reference internal" href="#">依赖注入与服务定位器（Dependency Injection/Service Location）</a><ul>
<li><a class="reference internal" href="#registering-services-in-the-container">使用容器注册服务（Registering services in the Container）</a><ul>
<li><a class="reference internal" href="#simple-registration">简单的注册（Simple Registration）</a><ul>
<li><a class="reference internal" href="#string">字符串(String)</a></li>
<li><a class="reference internal" href="#object">对象（Object）</a></li>
<li><a class="reference internal" href="#closures-anonymous-functions">闭包与匿名函数（Closures/Anonymous functions）</a></li>
</ul>
</li>
<li><a class="reference internal" href="#complex-registration">复杂的注册（Complex Registration）</a><ul>
<li><a class="reference internal" href="#constructor-injection">构造函数注入（Constructor Injection）</a></li>
<li><a class="reference internal" href="#setter-injection">设值注入（Setter Injection）</a></li>
<li><a class="reference internal" href="#properties-injection">属性注入（Properties Injection）</a></li>
</ul>
</li>
<li><a class="reference internal" href="#array-syntax">Array Syntax</a></li>
</ul>
</li>
<li><a class="reference internal" href="#resolving-services">服务解疑（Resolving Services）</a><ul>
<li><a class="reference internal" href="#events">Events</a></li>
</ul>
</li>
<li><a class="reference internal" href="#shared-services">共享服务（Shared services）</a></li>
<li><a class="reference internal" href="#manipulating-services-individually">单独操作服务（Manipulating services individually）</a></li>
<li><a class="reference internal" href="#instantiating-classes-via-the-service-container">通过服务容器实例化类（Instantiating classes via the Service Container）</a></li>
<li><a class="reference internal" href="#di-automatic-injecting-of-the-di-itself">自动注入 DI（Automatic Injecting of the DI itself）</a></li>
<li><a class="reference internal" href="#organizing-services-in-files">使用文件组织服务（Organizing services in files）</a></li>
<li><a class="reference internal" href="#accessing-the-di-in-a-static-way">使用静态的方式访问注入器（Accessing the DI in a static way）</a></li>
<li><a class="reference internal" href="#factory-default-di">注入器默认工厂（Factory Default DI）</a></li>
<li><a class="reference internal" href="#service-name-conventions">服务名称约定（Service Name Conventions）</a></li>
<li><a class="reference internal" href="#implementing-your-own-di">自定义注入器（Implementing your own DI）</a></li>
</ul>
</li>
</ul>

            <h4>上一个主题</h4>
            <p class="topless"><a href="samples.html" title="上一章">&lt; 示例列表（List of examples）</a></p>
            <h4>下一个主题</h4>
            <p class="topless"><a href="mvc.html" title="下一章">MVC 架构（The MVC Architecture） &gt;</a></p>
            <h3>本页</h3>
            <ul class="this-page-menu">
              <li><a href="../sources/reference/di.md" rel="nofollow">显示源代码</a></li>
            </ul>
        </td>
          <td class="second-box" valign="top">
            <div class="document">
                <div class="documentwrapper">
                  <div class="bodywrapper">
                    <div class="body" >
                      
  <div class="section" id="dependency-injection-service-location">
<h1>依赖注入与服务定位器（Dependency Injection/Service Location）<a class="headerlink" href="#dependency-injection-service-location" title="永久链接至标题">¶</a></h1>
<blockquote class="highlights">
<div>Before reading this section, it is wise to read <a class="reference internal" href="di-explained.html"><em>the section which explains why Phalcon uses service location and dependency injection</em></a>.</div></blockquote>
<p><a class="reference internal" href="../api/Phalcon_Di.html"><em>Phalcon\Di</em></a> 是一个实现依赖注入和定位服务的组件，而且它本身就是一个装载它们的容器。</p>
<p>因为Phalcon是高度解构的，整合框架的不同组件，使用 <a class="reference internal" href="../api/Phalcon_Di.html"><em>Phalcon\Di</em></a> 是必不可少的。开发者也可以使用这个组件去注入依赖和管理的应用程序中来自不同类的全局实例。</p>
<p>基本上，这个组件实现了 [控制反转](<a class="reference external" href="http://zh.wikipedia.org/wiki/%E6%8E%A7%E5%88%B6%E5%8F%8D%E8%BD%AC">http://zh.wikipedia.org/wiki/%E6%8E%A7%E5%88%B6%E5%8F%8D%E8%BD%AC</a>) 的模式。使用这种模式，组件的对象不用再使用setter或者构造函数去接受依赖实例，而是使用请求服务的依赖注入。这减少了总的复杂性，因为在组件内，只有一个方法去获取所需的依赖实例。</p>
<p>另外，该模式增加了代码的可测试性，从而使其不易出错。</p>
<div class="section" id="registering-services-in-the-container">
<h2>使用容器注册服务（Registering services in the Container）<a class="headerlink" href="#registering-services-in-the-container" title="永久链接至标题">¶</a></h2>
<p>框架本身或者开发者都可以注册服务。当一个组件A需要组件B(或者它的类的实例) 去操作，它可以通过容器去请求组件B，而不是创建一个新的组件B实例。</p>
<p>这个工作方法给我们提供了许多优势：</p>
<ul class="simple">
<li>我们可以很容易的使用一个我们自己建立的或者是第三方的组件去替换原有的组件。</li>
<li>我们完全控制对象的初始化，这让我们在传递它们的实例到组件之前，根据需要设置这些对象。</li>
<li>我们可以在一个结构化的和统一组件内获取全局实例。</li>
</ul>
<p>服务可以使用不同方式去定义：</p>
<div class="section" id="simple-registration">
<h3>简单的注册（Simple Registration）<a class="headerlink" href="#simple-registration" title="永久链接至标题">¶</a></h3>
<p>就像你之前看到的那样，这里有几种方法去注册服务。下面是简单调用的例子：</p>
<div class="section" id="string">
<h4>字符串(String)<a class="headerlink" href="#string" title="永久链接至标题">¶</a></h4>
<p>使用字符串注册服务需要一个有效的类名称，它将返回指定的类对象，如果类还没有加载的话，将使用自动加载器实例化对象。这种类型不允许向构造函数指定参数：</p>
<div class="highlight-php"><div class="highlight"><pre><span class="cp">&lt;?php</span>

<span class="c1">// 返回 new Phalcon\Http\Request(); 对象</span>
<span class="nv">$di</span><span class="o">-&gt;</span><span class="na">set</span><span class="p">(</span>
    <span class="s2">&quot;request&quot;</span><span class="p">,</span>
    <span class="s2">&quot;Phalcon</span><span class="se">\\</span><span class="s2">Http</span><span class="se">\\</span><span class="s2">Request&quot;</span>
<span class="p">);</span>
</pre></div>
</div>
</div>
<div class="section" id="object">
<h4>对象（Object）<a class="headerlink" href="#object" title="永久链接至标题">¶</a></h4>
<p>这种类型注册服务需要一个对象。实际上，这个服务不再需要初始化，因为它已经是一个对象，可以说，这是不是一个真正的依赖注入，但是如果你想强制总是返回相同的对象/值，使用这种方式还是有用的:</p>
<div class="highlight-php"><div class="highlight"><pre><span class="cp">&lt;?php</span>

<span class="k">use</span> <span class="nx">Phalcon\Http\Request</span><span class="p">;</span>

<span class="c1">// 返回 Phalcon\Http\Request(); 对象</span>
<span class="nv">$di</span><span class="o">-&gt;</span><span class="na">set</span><span class="p">(</span>
    <span class="s2">&quot;request&quot;</span><span class="p">,</span>
    <span class="k">new</span> <span class="nx">Request</span><span class="p">()</span>
<span class="p">);</span>
</pre></div>
</div>
</div>
<div class="section" id="closures-anonymous-functions">
<h4>闭包与匿名函数（Closures/Anonymous functions）<a class="headerlink" href="#closures-anonymous-functions" title="永久链接至标题">¶</a></h4>
<p>这个方法提供了更加自由的方式去注册依赖，但是如果你想从外部改变实例化的参数而不用改变注册服务的代码，这是很困难的：</p>
<div class="highlight-php"><div class="highlight"><pre><span class="cp">&lt;?php</span>

<span class="k">use</span> <span class="nx">Phalcon\Db\Adapter\Pdo\Mysql</span> <span class="k">as</span> <span class="nx">PdoMysql</span><span class="p">;</span>

<span class="nv">$di</span><span class="o">-&gt;</span><span class="na">set</span><span class="p">(</span>
    <span class="s2">&quot;db&quot;</span><span class="p">,</span>
    <span class="k">function</span> <span class="p">()</span> <span class="p">{</span>
        <span class="k">return</span> <span class="k">new</span> <span class="nx">PdoMysql</span><span class="p">(</span>
            <span class="p">[</span>
                <span class="s2">&quot;host&quot;</span>     <span class="o">=&gt;</span> <span class="s2">&quot;localhost&quot;</span><span class="p">,</span>
                <span class="s2">&quot;username&quot;</span> <span class="o">=&gt;</span> <span class="s2">&quot;root&quot;</span><span class="p">,</span>
                <span class="s2">&quot;password&quot;</span> <span class="o">=&gt;</span> <span class="s2">&quot;secret&quot;</span><span class="p">,</span>
                <span class="s2">&quot;dbname&quot;</span>   <span class="o">=&gt;</span> <span class="s2">&quot;blog&quot;</span><span class="p">,</span>
            <span class="p">]</span>
        <span class="p">);</span>
    <span class="p">}</span>
<span class="p">);</span>
</pre></div>
</div>
<p>这些限制是可以克服的，通过传递额外的变量到闭包函数里面：</p>
<div class="highlight-php"><div class="highlight"><pre><span class="cp">&lt;?php</span>

<span class="k">use</span> <span class="nx">Phalcon\Db\Adapter\Pdo\Mysql</span> <span class="k">as</span> <span class="nx">PdoMysql</span><span class="p">;</span>

<span class="c1">// 把当前域的$config变量传递给匿名函数使用</span>
<span class="nv">$di</span><span class="o">-&gt;</span><span class="na">set</span><span class="p">(</span>
    <span class="s2">&quot;db&quot;</span><span class="p">,</span>
    <span class="k">function</span> <span class="p">()</span> <span class="k">use</span> <span class="p">(</span><span class="nv">$config</span><span class="p">)</span> <span class="p">{</span>
        <span class="k">return</span> <span class="k">new</span> <span class="nx">PdoMysql</span><span class="p">(</span>
            <span class="p">[</span>
                <span class="s2">&quot;host&quot;</span>     <span class="o">=&gt;</span> <span class="nv">$config</span><span class="o">-&gt;</span><span class="na">host</span><span class="p">,</span>
                <span class="s2">&quot;username&quot;</span> <span class="o">=&gt;</span> <span class="nv">$config</span><span class="o">-&gt;</span><span class="na">username</span><span class="p">,</span>
                <span class="s2">&quot;password&quot;</span> <span class="o">=&gt;</span> <span class="nv">$config</span><span class="o">-&gt;</span><span class="na">password</span><span class="p">,</span>
                <span class="s2">&quot;dbname&quot;</span>   <span class="o">=&gt;</span> <span class="nv">$config</span><span class="o">-&gt;</span><span class="na">name</span><span class="p">,</span>
            <span class="p">]</span>
        <span class="p">);</span>
    <span class="p">}</span>
<span class="p">);</span>
</pre></div>
</div>
</div>
</div>
<div class="section" id="complex-registration">
<h3>复杂的注册（Complex Registration）<a class="headerlink" href="#complex-registration" title="永久链接至标题">¶</a></h3>
<p>如果要求不用实例化/解析服务，就可以改变定义服务的话，我们需要使用数组的方式去定义服务。使用数组去定义服务可以更加详细：</p>
<div class="highlight-php"><div class="highlight"><pre><span class="cp">&lt;?php</span>

<span class="k">use</span> <span class="nx">Phalcon\Logger\Adapter\File</span> <span class="k">as</span> <span class="nx">LoggerFile</span><span class="p">;</span>

<span class="c1">// 通过类名和参数，注册logger服务</span>
<span class="nv">$di</span><span class="o">-&gt;</span><span class="na">set</span><span class="p">(</span>
    <span class="s2">&quot;logger&quot;</span><span class="p">,</span>
    <span class="p">[</span>
        <span class="s2">&quot;className&quot;</span> <span class="o">=&gt;</span> <span class="s2">&quot;Phalcon</span><span class="se">\\</span><span class="s2">Logger</span><span class="se">\\</span><span class="s2">Adapter</span><span class="se">\\</span><span class="s2">File&quot;</span><span class="p">,</span>
        <span class="s2">&quot;arguments&quot;</span> <span class="o">=&gt;</span> <span class="p">[</span>
            <span class="p">[</span>
                <span class="s2">&quot;type&quot;</span>  <span class="o">=&gt;</span> <span class="s2">&quot;parameter&quot;</span><span class="p">,</span>
                <span class="s2">&quot;value&quot;</span> <span class="o">=&gt;</span> <span class="s2">&quot;../apps/logs/error.log&quot;</span><span class="p">,</span>
            <span class="p">]</span>
        <span class="p">]</span>
    <span class="p">]</span>
<span class="p">);</span>

<span class="c1">// 使用匿名函数的方式</span>
<span class="nv">$di</span><span class="o">-&gt;</span><span class="na">set</span><span class="p">(</span>
    <span class="s2">&quot;logger&quot;</span><span class="p">,</span>
    <span class="k">function</span> <span class="p">()</span> <span class="p">{</span>
        <span class="k">return</span> <span class="k">new</span> <span class="nx">LoggerFile</span><span class="p">(</span><span class="s2">&quot;../apps/logs/error.log&quot;</span><span class="p">);</span>
    <span class="p">}</span>
<span class="p">);</span>
</pre></div>
</div>
<p>上面两种注册服务的方式的结果是一样的。然而，使用数组定义的话，在需要的时候可以变更注册服务的参数：</p>
<div class="highlight-php"><div class="highlight"><pre><span class="cp">&lt;?php</span>

<span class="c1">// 改变logger服务的类名</span>
<span class="nv">$di</span><span class="o">-&gt;</span><span class="na">getService</span><span class="p">(</span><span class="s2">&quot;logger&quot;</span><span class="p">)</span><span class="o">-&gt;</span><span class="na">setClassName</span><span class="p">(</span><span class="s2">&quot;MyCustomLogger&quot;</span><span class="p">);</span>

<span class="c1">// 不用实例化就可以改变第一个参数值</span>
<span class="nv">$di</span><span class="o">-&gt;</span><span class="na">getService</span><span class="p">(</span><span class="s2">&quot;logger&quot;</span><span class="p">)</span><span class="o">-&gt;</span><span class="na">setParameter</span><span class="p">(</span>
    <span class="mi">0</span><span class="p">,</span>
    <span class="p">[</span>
        <span class="s2">&quot;type&quot;</span>  <span class="o">=&gt;</span> <span class="s2">&quot;parameter&quot;</span><span class="p">,</span>
        <span class="s2">&quot;value&quot;</span> <span class="o">=&gt;</span> <span class="s2">&quot;../apps/logs/error.log&quot;</span><span class="p">,</span>
    <span class="p">]</span>
<span class="p">);</span>
</pre></div>
</div>
<p>除了使用数组的语法注册服务，你还可以使用以下三种类型的依赖注入：</p>
<div class="section" id="constructor-injection">
<h4>构造函数注入（Constructor Injection）<a class="headerlink" href="#constructor-injection" title="永久链接至标题">¶</a></h4>
<p>这个注入方式是通过传递依赖/参数到类的构造函数。让我们假设我们有下面的组件：</p>
<div class="highlight-php"><div class="highlight"><pre><span class="cp">&lt;?php</span>

<span class="k">namespace</span> <span class="nx">SomeApp</span><span class="p">;</span>

<span class="k">use</span> <span class="nx">Phalcon\Http\Response</span><span class="p">;</span>

<span class="k">class</span> <span class="nc">SomeComponent</span>
<span class="p">{</span>
    <span class="k">protected</span> <span class="nv">$_response</span><span class="p">;</span>

    <span class="k">protected</span> <span class="nv">$_someFlag</span><span class="p">;</span>

    <span class="k">public</span> <span class="k">function</span> <span class="nf">__construct</span><span class="p">(</span><span class="nx">Response</span> <span class="nv">$response</span><span class="p">,</span> <span class="nv">$someFlag</span><span class="p">)</span>
    <span class="p">{</span>
        <span class="nv">$this</span><span class="o">-&gt;</span><span class="na">_response</span> <span class="o">=</span> <span class="nv">$response</span><span class="p">;</span>
        <span class="nv">$this</span><span class="o">-&gt;</span><span class="na">_someFlag</span> <span class="o">=</span> <span class="nv">$someFlag</span><span class="p">;</span>
    <span class="p">}</span>
<span class="p">}</span>
</pre></div>
</div>
<p>这个服务可以这样被注入：</p>
<div class="highlight-php"><div class="highlight"><pre><span class="cp">&lt;?php</span>

<span class="nv">$di</span><span class="o">-&gt;</span><span class="na">set</span><span class="p">(</span>
    <span class="s2">&quot;response&quot;</span><span class="p">,</span>
    <span class="p">[</span>
        <span class="s2">&quot;className&quot;</span> <span class="o">=&gt;</span> <span class="s2">&quot;Phalcon</span><span class="se">\\</span><span class="s2">Http</span><span class="se">\\</span><span class="s2">Response&quot;</span>
    <span class="p">]</span>
<span class="p">);</span>

<span class="nv">$di</span><span class="o">-&gt;</span><span class="na">set</span><span class="p">(</span>
    <span class="s2">&quot;someComponent&quot;</span><span class="p">,</span>
    <span class="p">[</span>
        <span class="s2">&quot;className&quot;</span> <span class="o">=&gt;</span> <span class="s2">&quot;SomeApp</span><span class="se">\\</span><span class="s2">SomeComponent&quot;</span><span class="p">,</span>
        <span class="s2">&quot;arguments&quot;</span> <span class="o">=&gt;</span> <span class="p">[</span>
            <span class="p">[</span><span class="s2">&quot;type&quot;</span> <span class="o">=&gt;</span> <span class="s2">&quot;service&quot;</span><span class="p">,</span> <span class="s2">&quot;name&quot;</span> <span class="o">=&gt;</span> <span class="s2">&quot;response&quot;</span><span class="p">],</span>
            <span class="p">[</span><span class="s2">&quot;type&quot;</span> <span class="o">=&gt;</span> <span class="s2">&quot;parameter&quot;</span><span class="p">,</span> <span class="s2">&quot;value&quot;</span> <span class="o">=&gt;</span> <span class="k">true</span><span class="p">],</span>
        <span class="p">]</span>
    <span class="p">]</span>
<span class="p">);</span>
</pre></div>
</div>
<p>reponse服务(<a class="reference internal" href="../api/Phalcon_Http_Response.html"><em>Phalcon\Http\Response</em></a>)作为第一个参数传递给构造函数，与此同时，一个布尔类型的值(true)作为第二个参数传递。</p>
</div>
<div class="section" id="setter-injection">
<h4>设值注入（Setter Injection）<a class="headerlink" href="#setter-injection" title="永久链接至标题">¶</a></h4>
<p>类中可能有setter去注入可选的依赖，前面那个class可以修改成通过setter来注入依赖的方式：</p>
<div class="highlight-php"><div class="highlight"><pre><span class="cp">&lt;?php</span>

<span class="k">namespace</span> <span class="nx">SomeApp</span><span class="p">;</span>

<span class="k">use</span> <span class="nx">Phalcon\Http\Response</span><span class="p">;</span>

<span class="k">class</span> <span class="nc">SomeComponent</span>
<span class="p">{</span>
    <span class="k">protected</span> <span class="nv">$_response</span><span class="p">;</span>

    <span class="k">protected</span> <span class="nv">$_someFlag</span><span class="p">;</span>

    <span class="k">public</span> <span class="k">function</span> <span class="nf">setResponse</span><span class="p">(</span><span class="nx">Response</span> <span class="nv">$response</span><span class="p">)</span>
    <span class="p">{</span>
        <span class="nv">$this</span><span class="o">-&gt;</span><span class="na">_response</span> <span class="o">=</span> <span class="nv">$response</span><span class="p">;</span>
    <span class="p">}</span>

    <span class="k">public</span> <span class="k">function</span> <span class="nf">setFlag</span><span class="p">(</span><span class="nv">$someFlag</span><span class="p">)</span>
    <span class="p">{</span>
        <span class="nv">$this</span><span class="o">-&gt;</span><span class="na">_someFlag</span> <span class="o">=</span> <span class="nv">$someFlag</span><span class="p">;</span>
    <span class="p">}</span>
<span class="p">}</span>
</pre></div>
</div>
<p>用setter方式来注入的服务可以通过下面的方式来注册：</p>
<div class="highlight-php"><div class="highlight"><pre><span class="cp">&lt;?php</span>

<span class="nv">$di</span><span class="o">-&gt;</span><span class="na">set</span><span class="p">(</span>
    <span class="s2">&quot;response&quot;</span><span class="p">,</span>
    <span class="p">[</span>
        <span class="s2">&quot;className&quot;</span> <span class="o">=&gt;</span> <span class="s2">&quot;Phalcon</span><span class="se">\\</span><span class="s2">Http</span><span class="se">\\</span><span class="s2">Response&quot;</span>
    <span class="p">]</span>
<span class="p">);</span>

<span class="nv">$di</span><span class="o">-&gt;</span><span class="na">set</span><span class="p">(</span>
    <span class="s2">&quot;someComponent&quot;</span><span class="p">,</span>
    <span class="p">[</span>
        <span class="s2">&quot;className&quot;</span> <span class="o">=&gt;</span> <span class="s2">&quot;SomeApp</span><span class="se">\\</span><span class="s2">SomeComponent&quot;</span><span class="p">,</span>
        <span class="s2">&quot;calls&quot;</span>     <span class="o">=&gt;</span> <span class="p">[</span>
            <span class="p">[</span>
                <span class="s2">&quot;method&quot;</span>    <span class="o">=&gt;</span> <span class="s2">&quot;setResponse&quot;</span><span class="p">,</span>
                <span class="s2">&quot;arguments&quot;</span> <span class="o">=&gt;</span> <span class="p">[</span>
                    <span class="p">[</span>
                        <span class="s2">&quot;type&quot;</span> <span class="o">=&gt;</span> <span class="s2">&quot;service&quot;</span><span class="p">,</span>
                        <span class="s2">&quot;name&quot;</span> <span class="o">=&gt;</span> <span class="s2">&quot;response&quot;</span><span class="p">,</span>
                    <span class="p">]</span>
                <span class="p">]</span>
            <span class="p">],</span>
            <span class="p">[</span>
                <span class="s2">&quot;method&quot;</span>    <span class="o">=&gt;</span> <span class="s2">&quot;setFlag&quot;</span><span class="p">,</span>
                <span class="s2">&quot;arguments&quot;</span> <span class="o">=&gt;</span> <span class="p">[</span>
                    <span class="p">[</span>
                        <span class="s2">&quot;type&quot;</span>  <span class="o">=&gt;</span> <span class="s2">&quot;parameter&quot;</span><span class="p">,</span>
                        <span class="s2">&quot;value&quot;</span> <span class="o">=&gt;</span> <span class="k">true</span><span class="p">,</span>
                    <span class="p">]</span>
                <span class="p">]</span>
            <span class="p">]</span>
        <span class="p">]</span>
    <span class="p">]</span>
<span class="p">);</span>
</pre></div>
</div>
</div>
<div class="section" id="properties-injection">
<h4>属性注入（Properties Injection）<a class="headerlink" href="#properties-injection" title="永久链接至标题">¶</a></h4>
<p>这是一个不太常用的方式，这种方式的注入是通过类的public属性来注入：</p>
<div class="highlight-php"><div class="highlight"><pre><span class="cp">&lt;?php</span>

<span class="k">namespace</span> <span class="nx">SomeApp</span><span class="p">;</span>

<span class="k">use</span> <span class="nx">Phalcon\Http\Response</span><span class="p">;</span>

<span class="k">class</span> <span class="nc">SomeComponent</span>
<span class="p">{</span>
    <span class="k">public</span> <span class="nv">$response</span><span class="p">;</span>

    <span class="k">public</span> <span class="nv">$someFlag</span><span class="p">;</span>
<span class="p">}</span>
</pre></div>
</div>
<p>通过属性注入的服务，可以像下面这样注册：</p>
<div class="highlight-php"><div class="highlight"><pre><span class="cp">&lt;?php</span>

<span class="nv">$di</span><span class="o">-&gt;</span><span class="na">set</span><span class="p">(</span>
    <span class="s2">&quot;response&quot;</span><span class="p">,</span>
    <span class="p">[</span>
        <span class="s2">&quot;className&quot;</span> <span class="o">=&gt;</span> <span class="s2">&quot;Phalcon</span><span class="se">\\</span><span class="s2">Http</span><span class="se">\\</span><span class="s2">Response&quot;</span>
    <span class="p">]</span>
<span class="p">);</span>

<span class="nv">$di</span><span class="o">-&gt;</span><span class="na">set</span><span class="p">(</span>
    <span class="s2">&quot;someComponent&quot;</span><span class="p">,</span>
    <span class="p">[</span>
        <span class="s2">&quot;className&quot;</span>  <span class="o">=&gt;</span> <span class="s2">&quot;SomeApp</span><span class="se">\\</span><span class="s2">SomeComponent&quot;</span><span class="p">,</span>
        <span class="s2">&quot;properties&quot;</span> <span class="o">=&gt;</span> <span class="p">[</span>
            <span class="p">[</span>
                <span class="s2">&quot;name&quot;</span>  <span class="o">=&gt;</span> <span class="s2">&quot;response&quot;</span><span class="p">,</span>
                <span class="s2">&quot;value&quot;</span> <span class="o">=&gt;</span> <span class="p">[</span>
                    <span class="s2">&quot;type&quot;</span> <span class="o">=&gt;</span> <span class="s2">&quot;service&quot;</span><span class="p">,</span>
                    <span class="s2">&quot;name&quot;</span> <span class="o">=&gt;</span> <span class="s2">&quot;response&quot;</span><span class="p">,</span>
                <span class="p">]</span>
            <span class="p">],</span>
            <span class="p">[</span>
                <span class="s2">&quot;name&quot;</span>  <span class="o">=&gt;</span> <span class="s2">&quot;someFlag&quot;</span><span class="p">,</span>
                <span class="s2">&quot;value&quot;</span> <span class="o">=&gt;</span> <span class="p">[</span>
                    <span class="s2">&quot;type&quot;</span>  <span class="o">=&gt;</span> <span class="s2">&quot;parameter&quot;</span><span class="p">,</span>
                    <span class="s2">&quot;value&quot;</span> <span class="o">=&gt;</span> <span class="k">true</span><span class="p">,</span>
                <span class="p">]</span>
            <span class="p">]</span>
        <span class="p">]</span>
    <span class="p">]</span>
<span class="p">);</span>
</pre></div>
</div>
<p>支持包括下面的参数类型：</p>
<p>解析一个定义复杂的服务也许性能上稍微慢于先前看到的简单定义。但是，这提供了一个更强大的方式来定义和注入服务。</p>
<p>混合不同类型的定义是可以的，每个人可以应用需要决定什么样的注册服务的方式是最适当的。</p>
</div>
</div>
<div class="section" id="array-syntax">
<h3>Array Syntax<a class="headerlink" href="#array-syntax" title="永久链接至标题">¶</a></h3>
<p>使用数组的方式去注册服务也是可以的：</p>
<div class="highlight-php"><div class="highlight"><pre><span class="cp">&lt;?php</span>

<span class="k">use</span> <span class="nx">Phalcon\Di</span><span class="p">;</span>
<span class="k">use</span> <span class="nx">Phalcon\Http\Request</span><span class="p">;</span>

<span class="c1">// 创建一个依赖注入容器</span>
<span class="nv">$di</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">Di</span><span class="p">();</span>

<span class="c1">// 通过类名称设置服务</span>
<span class="nv">$di</span><span class="p">[</span><span class="s2">&quot;request&quot;</span><span class="p">]</span> <span class="o">=</span> <span class="s2">&quot;Phalcon</span><span class="se">\\</span><span class="s2">Http</span><span class="se">\\</span><span class="s2">Request&quot;</span><span class="p">;</span>

<span class="c1">// 使用匿名函数去设置服务，这个实例将被延迟加载</span>
<span class="nv">$di</span><span class="p">[</span><span class="s2">&quot;request&quot;</span><span class="p">]</span> <span class="o">=</span> <span class="k">function</span> <span class="p">()</span> <span class="p">{</span>
    <span class="k">return</span> <span class="k">new</span> <span class="nx">Request</span><span class="p">();</span>
<span class="p">};</span>

<span class="c1">// 直接注册一个实例</span>
<span class="nv">$di</span><span class="p">[</span><span class="s2">&quot;request&quot;</span><span class="p">]</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">Request</span><span class="p">();</span>

<span class="c1">// 使用数组方式定义服务</span>
<span class="nv">$di</span><span class="p">[</span><span class="s2">&quot;request&quot;</span><span class="p">]</span> <span class="o">=</span> <span class="p">[</span>
    <span class="s2">&quot;className&quot;</span> <span class="o">=&gt;</span> <span class="s2">&quot;Phalcon</span><span class="se">\\</span><span class="s2">Http</span><span class="se">\\</span><span class="s2">Request&quot;</span>
<span class="p">];</span>
</pre></div>
</div>
<p>在上面的例子中，当框架需要访问request服务的内容，它会在容器里面查找名为‘request’的服务。
在容器中将返回所需要的服务的实例。当有需要时，开发者可能最终需要替换这个组件。</p>
<p>每个方法（在上面的例子证明）用于设置/注册服务方面具都具有优势和劣势。这是由开发者和特别的要求决定具体使用哪个。</p>
<p>通过字符串设置一个服务是很简单，但是缺乏灵活性。通过数组设置服务提供了更加灵活的方式，但是使代码更复杂。匿名函数是上述两者之间的一个很好的平衡，但是会导致比预期的更多维护。</p>
<p><a class="reference internal" href="../api/Phalcon_Di.html"><em>Phalcon\Di</em></a> 对每个储存的服务提供了延迟加载。除非开发者选择直接实例化一个对象并将其存储在容器中，任何储存在里面的对象(通过数组，字符串等等设置的)都将延迟加载，即只要当使用到时才实例化。</p>
</div>
</div>
<div class="section" id="resolving-services">
<h2>服务解疑（Resolving Services）<a class="headerlink" href="#resolving-services" title="永久链接至标题">¶</a></h2>
<p>从容器中获取一个服务是一件简单的事情，只要通过“get”方法就可以。这将返回一个服务的新实例：</p>
<div class="highlight-php"><div class="highlight"><pre><span class="cp">&lt;?php</span> <span class="nv">$request</span> <span class="o">=</span> <span class="nv">$di</span><span class="o">-&gt;</span><span class="na">get</span><span class="p">(</span><span class="s2">&quot;request&quot;</span><span class="p">);</span>
</pre></div>
</div>
<p>或者通过魔术方法的方式获取：</p>
<div class="highlight-php"><div class="highlight"><pre><span class="cp">&lt;?php</span>

<span class="nv">$request</span> <span class="o">=</span> <span class="nv">$di</span><span class="o">-&gt;</span><span class="na">getRequest</span><span class="p">();</span>
</pre></div>
</div>
<p>或者通过访问数组的方式获取：</p>
<div class="highlight-php"><div class="highlight"><pre><span class="cp">&lt;?php</span>

<span class="nv">$request</span> <span class="o">=</span> <span class="nv">$di</span><span class="p">[</span><span class="s2">&quot;request&quot;</span><span class="p">];</span>
</pre></div>
</div>
<p>参数可以传递到构造函数中，通过添加一个数组的参数到get方法中：</p>
<div class="highlight-php"><div class="highlight"><pre><span class="cp">&lt;?php</span>

<span class="c1">// 将返回：new MyComponent(&quot;some-parameter&quot;, &quot;other&quot;)</span>
<span class="nv">$component</span> <span class="o">=</span> <span class="nv">$di</span><span class="o">-&gt;</span><span class="na">get</span><span class="p">(</span><span class="s2">&quot;MyComponent&quot;</span><span class="p">,</span> <span class="p">[</span><span class="s2">&quot;some-parameter&quot;</span><span class="p">,</span> <span class="s2">&quot;other&quot;</span><span class="p">]);</span>
</pre></div>
</div>
<div class="section" id="events">
<h3>Events<a class="headerlink" href="#events" title="永久链接至标题">¶</a></h3>
<p><a class="reference internal" href="../api/Phalcon_Di.html"><em>Phalcon\Di</em></a> is able to send events to an <a class="reference internal" href="events.html"><em>EventsManager</em></a> if it is present.
Events are triggered using the type &#8220;di&#8221;. Some events when returning boolean false could stop the active operation.
The following events are supported:</p>
<table border="1" class="docutils">
<colgroup>
<col width="11%" />
<col width="67%" />
<col width="11%" />
<col width="10%" />
</colgroup>
<thead valign="bottom">
<tr class="row-odd"><th class="head">Event Name</th>
<th class="head">Triggered</th>
<th class="head">Can stop operation?</th>
<th class="head">Triggered on</th>
</tr>
</thead>
<tbody valign="top">
<tr class="row-even"><td>beforeServiceResolve</td>
<td>Triggered before resolve service. Listeners receive the service name and the parameters passed to it.</td>
<td>No</td>
<td>Listeners</td>
</tr>
<tr class="row-odd"><td>afterServiceResolve</td>
<td>Triggered after resolve service. Listeners receive the service name, instance, and the parameters passed to it.</td>
<td>No</td>
<td>Listeners</td>
</tr>
</tbody>
</table>
</div>
</div>
<div class="section" id="shared-services">
<h2>共享服务（Shared services）<a class="headerlink" href="#shared-services" title="永久链接至标题">¶</a></h2>
<p>服务可以注册成“shared”类型的服务，这意味着这个服务将使用 [单例模式](<a class="reference external" href="http://zh.wikipedia.org/wiki/%E5%8D%95%E4%BE%8B%E6%A8%A1%E5%BC%8F">http://zh.wikipedia.org/wiki/%E5%8D%95%E4%BE%8B%E6%A8%A1%E5%BC%8F</a>) 运行，
一旦服务被首次解析后，这个实例将被保存在容器中，之后的每次请求都在容器中查找并返回这个实例</p>
<div class="highlight-php"><div class="highlight"><pre><span class="cp">&lt;?php</span>

<span class="k">use</span> <span class="nx">Phalcon\Session\Adapter\Files</span> <span class="k">as</span> <span class="nx">SessionFiles</span><span class="p">;</span>

<span class="c1">// 把session服务注册成“shared”类型</span>
<span class="nv">$di</span><span class="o">-&gt;</span><span class="na">setShared</span><span class="p">(</span>
    <span class="s2">&quot;session&quot;</span><span class="p">,</span>
    <span class="k">function</span> <span class="p">()</span> <span class="p">{</span>
        <span class="nv">$session</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">SessionFiles</span><span class="p">();</span>

        <span class="nv">$session</span><span class="o">-&gt;</span><span class="na">start</span><span class="p">();</span>

        <span class="k">return</span> <span class="nv">$session</span><span class="p">;</span>
    <span class="p">}</span>
<span class="p">);</span>

<span class="nv">$session</span> <span class="o">=</span> <span class="nv">$di</span><span class="o">-&gt;</span><span class="na">get</span><span class="p">(</span><span class="s2">&quot;session&quot;</span><span class="p">);</span> <span class="c1">// 第一次获取session服务时，session服务将实例化</span>
<span class="nv">$session</span> <span class="o">=</span> <span class="nv">$di</span><span class="o">-&gt;</span><span class="na">getSession</span><span class="p">();</span>   <span class="c1">// 第二次获取时，不再实例化，直接返回第一次实例化的对象</span>
</pre></div>
</div>
<p>另一种方式去注册一个“shared”类型的服务是，传递“set”服务的时候，把true作为第三个参数传递过去：</p>
<div class="highlight-php"><div class="highlight"><pre><span class="cp">&lt;?php</span>

<span class="c1">// 把session服务注册成“shared”类型</span>
<span class="nv">$di</span><span class="o">-&gt;</span><span class="na">set</span><span class="p">(</span>
    <span class="s2">&quot;session&quot;</span><span class="p">,</span>
    <span class="k">function</span> <span class="p">()</span> <span class="p">{</span>
        <span class="c1">// ...</span>
    <span class="p">},</span>
    <span class="k">true</span>
<span class="p">);</span>
</pre></div>
</div>
<p>如果一个服务不是注册成“shared”类型，而你又想从DI中获取服务的“shared”实例，你可以使用getShared方法：</p>
<div class="highlight-php"><div class="highlight"><pre><span class="cp">&lt;?php</span>

<span class="nv">$request</span> <span class="o">=</span> <span class="nv">$di</span><span class="o">-&gt;</span><span class="na">getShared</span><span class="p">(</span><span class="s2">&quot;request&quot;</span><span class="p">);</span>
</pre></div>
</div>
</div>
<div class="section" id="manipulating-services-individually">
<h2>单独操作服务（Manipulating services individually）<a class="headerlink" href="#manipulating-services-individually" title="永久链接至标题">¶</a></h2>
<p>一旦服务被注册到服务容器中，你可以单独操作它：</p>
<div class="highlight-php"><div class="highlight"><pre><span class="cp">&lt;?php</span>

<span class="k">use</span> <span class="nx">Phalcon\Http\Request</span><span class="p">;</span>

<span class="c1">// 注册request服务</span>
<span class="nv">$di</span><span class="o">-&gt;</span><span class="na">set</span><span class="p">(</span><span class="s2">&quot;request&quot;</span><span class="p">,</span> <span class="s2">&quot;Phalcon</span><span class="se">\\</span><span class="s2">Http</span><span class="se">\\</span><span class="s2">Request&quot;</span><span class="p">);</span>

<span class="c1">// 获取服务</span>
<span class="nv">$requestService</span> <span class="o">=</span> <span class="nv">$di</span><span class="o">-&gt;</span><span class="na">getService</span><span class="p">(</span><span class="s2">&quot;request&quot;</span><span class="p">);</span>

<span class="c1">// 改变它的定义</span>
<span class="nv">$requestService</span><span class="o">-&gt;</span><span class="na">setDefinition</span><span class="p">(</span>
    <span class="k">function</span> <span class="p">()</span> <span class="p">{</span>
        <span class="k">return</span> <span class="k">new</span> <span class="nx">Request</span><span class="p">();</span>
    <span class="p">}</span>
<span class="p">);</span>

<span class="c1">// 修改成shared类型</span>
<span class="nv">$requestService</span><span class="o">-&gt;</span><span class="na">setShared</span><span class="p">(</span><span class="k">true</span><span class="p">);</span>

<span class="c1">// 解析服务（返回Phalcon\Http\Request实例）</span>
<span class="nv">$request</span> <span class="o">=</span> <span class="nv">$requestService</span><span class="o">-&gt;</span><span class="na">resolve</span><span class="p">();</span>
</pre></div>
</div>
</div>
<div class="section" id="instantiating-classes-via-the-service-container">
<h2>通过服务容器实例化类（Instantiating classes via the Service Container）<a class="headerlink" href="#instantiating-classes-via-the-service-container" title="永久链接至标题">¶</a></h2>
<p>当你从服务容器中请求一个服务，如果找不到具有相同名称的服务，它将尝试去加载以这个服务为名称的类。利用这个的行为，
我们可以代替任意一个类，通过简单的利用服务的名称来注册：</p>
<div class="highlight-php"><div class="highlight"><pre><span class="cp">&lt;?php</span>

<span class="c1">// 把一个控制器注册为服务</span>
<span class="nv">$di</span><span class="o">-&gt;</span><span class="na">set</span><span class="p">(</span>
    <span class="s2">&quot;IndexController&quot;</span><span class="p">,</span>
    <span class="k">function</span> <span class="p">()</span> <span class="p">{</span>
        <span class="nv">$component</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">Component</span><span class="p">();</span>

        <span class="k">return</span> <span class="nv">$component</span><span class="p">;</span>
    <span class="p">},</span>
    <span class="k">true</span>
<span class="p">);</span>

<span class="c1">// 把一个控制器注册为服务</span>
<span class="nv">$di</span><span class="o">-&gt;</span><span class="na">set</span><span class="p">(</span>
    <span class="s2">&quot;MyOtherComponent&quot;</span><span class="p">,</span>
    <span class="k">function</span> <span class="p">()</span> <span class="p">{</span>
        <span class="c1">// 实际上返回另外一个组件</span>
        <span class="nv">$component</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">AnotherComponent</span><span class="p">();</span>

        <span class="k">return</span> <span class="nv">$component</span><span class="p">;</span>
    <span class="p">}</span>
<span class="p">);</span>

<span class="c1">// 获取通过服务容器创建的对象</span>
<span class="nv">$myComponent</span> <span class="o">=</span> <span class="nv">$di</span><span class="o">-&gt;</span><span class="na">get</span><span class="p">(</span><span class="s2">&quot;MyOtherComponent&quot;</span><span class="p">);</span>
</pre></div>
</div>
<p>你可以利用这种方式，通过服务容器来总是实例化你的类(即是他们没有注册为服务)，
DI会回退到一个有效的自动加载类中，去加载这个类。通过这样做，以后你可以轻松替换任意的类通过为它实现一个定义。</p>
</div>
<div class="section" id="di-automatic-injecting-of-the-di-itself">
<h2>自动注入 DI（Automatic Injecting of the DI itself）<a class="headerlink" href="#di-automatic-injecting-of-the-di-itself" title="永久链接至标题">¶</a></h2>
<p>如果一个类或者组件需要用到DI服务，你需要在你的类中实现 <a class="reference internal" href="../api/Phalcon_Di_InjectionAwareInterface.html"><em>Phalcon\Di\InjectionAwareInterface</em></a> 接口，
这样就可以在实例化这个类的对象时自动注入DI的服务:</p>
<div class="highlight-php"><div class="highlight"><pre><span class="cp">&lt;?php</span>

<span class="k">use</span> <span class="nx">Phalcon\DiInterface</span><span class="p">;</span>
<span class="k">use</span> <span class="nx">Phalcon\Di\InjectionAwareInterface</span><span class="p">;</span>

<span class="k">class</span> <span class="nc">MyClass</span> <span class="k">implements</span> <span class="nx">InjectionAwareInterface</span>
<span class="p">{</span>
    <span class="k">protected</span> <span class="nv">$_di</span><span class="p">;</span>

    <span class="k">public</span> <span class="k">function</span> <span class="nf">setDi</span><span class="p">(</span><span class="nx">DiInterface</span> <span class="nv">$di</span><span class="p">)</span>
    <span class="p">{</span>
        <span class="nv">$this</span><span class="o">-&gt;</span><span class="na">_di</span> <span class="o">=</span> <span class="nv">$di</span><span class="p">;</span>
    <span class="p">}</span>

    <span class="k">public</span> <span class="k">function</span> <span class="nf">getDi</span><span class="p">()</span>
    <span class="p">{</span>
        <span class="k">return</span> <span class="nv">$this</span><span class="o">-&gt;</span><span class="na">_di</span><span class="p">;</span>
    <span class="p">}</span>
<span class="p">}</span>
</pre></div>
</div>
<p>按照上面这样，一旦服务被解析，<code class="code docutils literal"><span class="pre">$di</span></code> 对象将自动传递到 <code class="code docutils literal"><span class="pre">setDi()</span></code> 方法：</p>
<div class="highlight-php"><div class="highlight"><pre><span class="cp">&lt;?php</span>

<span class="c1">// 注册服务</span>
<span class="nv">$di</span><span class="o">-&gt;</span><span class="na">set</span><span class="p">(</span><span class="s2">&quot;myClass&quot;</span><span class="p">,</span> <span class="s2">&quot;MyClass&quot;</span><span class="p">);</span>

<span class="c1">// 解析服务（注意：将自动调用$myClass-&gt;setDi($di)方法）</span>
<span class="nv">$myClass</span> <span class="o">=</span> <span class="nv">$di</span><span class="o">-&gt;</span><span class="na">get</span><span class="p">(</span><span class="s2">&quot;myClass&quot;</span><span class="p">);</span>
</pre></div>
</div>
</div>
<div class="section" id="organizing-services-in-files">
<h2>使用文件组织服务（Organizing services in files）<a class="headerlink" href="#organizing-services-in-files" title="永久链接至标题">¶</a></h2>
<p>你可以更好的组织你的应用，通过移动注册的服务到独立的文件里面，而不是全部写在应用的引导文件中：</p>
<div class="highlight-php"><div class="highlight"><pre><span class="cp">&lt;?php</span>

<span class="nv">$di</span><span class="o">-&gt;</span><span class="na">set</span><span class="p">(</span>
    <span class="s2">&quot;router&quot;</span><span class="p">,</span>
    <span class="k">function</span> <span class="p">()</span> <span class="p">{</span>
        <span class="k">return</span> <span class="k">include</span> <span class="s2">&quot;../app/config/routes.php&quot;</span><span class="p">;</span>
    <span class="p">}</span>
<span class="p">);</span>
</pre></div>
</div>
<p>这样，在文件(&#8221;../app/config/routes.php&#8221;)中，返回已解析的对象：</p>
<div class="highlight-php"><div class="highlight"><pre><span class="cp">&lt;?php</span>

<span class="nv">$router</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">MyRouter</span><span class="p">();</span>

<span class="nv">$router</span><span class="o">-&gt;</span><span class="na">post</span><span class="p">(</span><span class="s2">&quot;/login&quot;</span><span class="p">);</span>

<span class="k">return</span> <span class="nv">$router</span><span class="p">;</span>
</pre></div>
</div>
</div>
<div class="section" id="accessing-the-di-in-a-static-way">
<h2>使用静态的方式访问注入器（Accessing the DI in a static way）<a class="headerlink" href="#accessing-the-di-in-a-static-way" title="永久链接至标题">¶</a></h2>
<p>如果需要的话，你可以访问最新创建的DI对象，通过下面这种静态方法的方式：</p>
<div class="highlight-php"><div class="highlight"><pre><span class="cp">&lt;?php</span>

<span class="k">use</span> <span class="nx">Phalcon\Di</span><span class="p">;</span>

<span class="k">class</span> <span class="nc">SomeComponent</span>
<span class="p">{</span>
    <span class="k">public</span> <span class="k">static</span> <span class="k">function</span> <span class="nf">someMethod</span><span class="p">()</span>
    <span class="p">{</span>
        <span class="c1">// 获取session服务</span>
        <span class="nv">$session</span> <span class="o">=</span> <span class="nx">Di</span><span class="o">::</span><span class="na">getDefault</span><span class="p">()</span><span class="o">-&gt;</span><span class="na">getSession</span><span class="p">();</span>
    <span class="p">}</span>
<span class="p">}</span>
</pre></div>
</div>
</div>
<div class="section" id="factory-default-di">
<h2>注入器默认工厂（Factory Default DI）<a class="headerlink" href="#factory-default-di" title="永久链接至标题">¶</a></h2>
<p>尽管Phalcon的解耦性质为我们提供了很大的自由度和灵活性，也许我们只是单纯的想使用它作为一个全栈框架。
为了达到这点，框架提供了变种的 <a class="reference internal" href="../api/Phalcon_Di.html"><em>Phalcon\Di</em></a> 叫 <a class="reference internal" href="../api/Phalcon_Di_FactoryDefault.html"><em>Phalcon\Di\FactoryDefault</em></a> 。这个类会自动注册相应的服务，并捆绑在一起作为一个全栈框架。</p>
<div class="highlight-php"><div class="highlight"><pre><span class="cp">&lt;?php</span>

<span class="k">use</span> <span class="nx">Phalcon\Di\FactoryDefault</span><span class="p">;</span>

<span class="nv">$di</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">FactoryDefault</span><span class="p">();</span>
</pre></div>
</div>
</div>
<div class="section" id="service-name-conventions">
<h2>服务名称约定（Service Name Conventions）<a class="headerlink" href="#service-name-conventions" title="永久链接至标题">¶</a></h2>
<p>尽管你可以用你喜欢的名字来注册服务，但是Phalcon有一些命名约定，这些约定让你在需要的时候，可以获得正确的（内置）服务。</p>
<table border="1" class="docutils">
<colgroup>
<col width="11%" />
<col width="24%" />
<col width="54%" />
<col width="10%" />
</colgroup>
<thead valign="bottom">
<tr class="row-odd"><th class="head">服务名称</th>
<th class="head">介绍</th>
<th class="head">默认</th>
<th class="head">是否是shared服务</th>
</tr>
</thead>
<tbody valign="top">
<tr class="row-even"><td>dispatcher</td>
<td>控制器调度服务</td>
<td><a class="reference internal" href="../api/Phalcon_Mvc_Dispatcher.html"><em>Phalcon\Mvc\Dispatcher</em></a></td>
<td>是</td>
</tr>
<tr class="row-odd"><td>router</td>
<td>路由服务</td>
<td><a class="reference internal" href="../api/Phalcon_Mvc_Router.html"><em>Phalcon\Mvc\Router</em></a></td>
<td>是</td>
</tr>
<tr class="row-even"><td>url</td>
<td>URL生成服务</td>
<td><a class="reference internal" href="../api/Phalcon_Mvc_Url.html"><em>Phalcon\Mvc\Url</em></a></td>
<td>是</td>
</tr>
<tr class="row-odd"><td>request</td>
<td>HTTP 请求环境服务</td>
<td><a class="reference internal" href="../api/Phalcon_Http_Request.html"><em>Phalcon\Http\Request</em></a></td>
<td>是</td>
</tr>
<tr class="row-even"><td>response</td>
<td>HTTP响应环境服务</td>
<td><a class="reference internal" href="../api/Phalcon_Http_Response.html"><em>Phalcon\Http\Response</em></a></td>
<td>是</td>
</tr>
<tr class="row-odd"><td>cookies</td>
<td>HTTP Cookie管理服务</td>
<td><a class="reference internal" href="../api/Phalcon_Http_Response_Cookies.html"><em>Phalcon\Http\Response\Cookies</em></a></td>
<td>是</td>
</tr>
<tr class="row-even"><td>filter</td>
<td>输入过滤服务</td>
<td><a class="reference internal" href="../api/Phalcon_Filter.html"><em>Phalcon\Filter</em></a></td>
<td>是</td>
</tr>
<tr class="row-odd"><td>flash</td>
<td>闪现信息服务</td>
<td><a class="reference internal" href="../api/Phalcon_Flash_Direct.html"><em>Phalcon\Flash\Direct</em></a></td>
<td>是</td>
</tr>
<tr class="row-even"><td>flashSession</td>
<td>闪现session信息服务</td>
<td><a class="reference internal" href="../api/Phalcon_Flash_Session.html"><em>Phalcon\Flash\Session</em></a></td>
<td>是</td>
</tr>
<tr class="row-odd"><td>session</td>
<td>session服务</td>
<td><a class="reference internal" href="../api/Phalcon_Session_Adapter_Files.html"><em>Phalcon\Session\Adapter\Files</em></a></td>
<td>是</td>
</tr>
<tr class="row-even"><td>eventsManager</td>
<td>事件管理服务</td>
<td><a class="reference internal" href="../api/Phalcon_Events_Manager.html"><em>Phalcon\Events\Manager</em></a></td>
<td>是</td>
</tr>
<tr class="row-odd"><td>db</td>
<td>底层数据库连接服务</td>
<td><a class="reference internal" href="../api/Phalcon_Db.html"><em>Phalcon\Db</em></a></td>
<td>是</td>
</tr>
<tr class="row-even"><td>security</td>
<td>安全助手</td>
<td><a class="reference internal" href="../api/Phalcon_Security.html"><em>Phalcon\Security</em></a></td>
<td>是</td>
</tr>
<tr class="row-odd"><td>crypt</td>
<td>加密/解密数据</td>
<td><a class="reference internal" href="../api/Phalcon_Crypt.html"><em>Phalcon\Crypt</em></a></td>
<td>是</td>
</tr>
<tr class="row-even"><td>tag</td>
<td>HTML生成助手</td>
<td><a class="reference internal" href="../api/Phalcon_Tag.html"><em>Phalcon\Tag</em></a></td>
<td>是</td>
</tr>
<tr class="row-odd"><td>escaper</td>
<td>内容(HTML)转义</td>
<td><a class="reference internal" href="../api/Phalcon_Escaper.html"><em>Phalcon\Escaper</em></a></td>
<td>是</td>
</tr>
<tr class="row-even"><td>annotations</td>
<td>注释分析器</td>
<td><a class="reference internal" href="../api/Phalcon_Annotations_Adapter_Memory.html"><em>Phalcon\Annotations\Adapter\Memory</em></a></td>
<td>是</td>
</tr>
<tr class="row-odd"><td>modelsManager</td>
<td>model管理服务</td>
<td><a class="reference internal" href="../api/Phalcon_Mvc_Model_Manager.html"><em>Phalcon\Mvc\Model\Manager</em></a></td>
<td>是</td>
</tr>
<tr class="row-even"><td>modelsMetadata</td>
<td>model元数据服务</td>
<td><a class="reference internal" href="../api/Phalcon_Mvc_Model_MetaData_Memory.html"><em>Phalcon\Mvc\Model\MetaData\Memory</em></a></td>
<td>是</td>
</tr>
<tr class="row-odd"><td>transactionManager</td>
<td>model事务管理服务</td>
<td><a class="reference internal" href="../api/Phalcon_Mvc_Model_Transaction_Manager.html"><em>Phalcon\Mvc\Model\Transaction\Manager</em></a></td>
<td>是</td>
</tr>
<tr class="row-even"><td>modelsCache</td>
<td>model的缓存服务</td>
<td>None</td>
<td>No</td>
</tr>
<tr class="row-odd"><td>viewsCache</td>
<td>view的缓存服务</td>
<td>None</td>
<td>No</td>
</tr>
</tbody>
</table>
</div>
<div class="section" id="implementing-your-own-di">
<h2>自定义注入器（Implementing your own DI）<a class="headerlink" href="#implementing-your-own-di" title="永久链接至标题">¶</a></h2>
<p>如果你要创建一个自定义注入器或者继承一个已有的，接口 <a class="reference internal" href="../api/Phalcon_DiInterface.html"><em>Phalcon\DiInterface</em></a> 必须被实现。</p>
</div>
</div>


                    </div>
                  </div>
                </div>
            </div>
          </td>
        </tr>
      </table>
    <div class="related">
      <ul>
        <li class="right" >
          <a href="../genindex.html" title="总目录"
             >索引</a></li>
        <li class="right" >
          <a href="mvc.html" title="MVC 架构（The MVC Architecture）"
             >下一页</a> |</li>
        <li class="right" >
          <a href="samples.html" title="示例列表（List of examples）"
             >上一页</a> |</li> 
      </ul>
    </div>

      <div class="prefooter">
  <div class="container">
      <div class="row">
          <div class="col-sm-3 text-right">
              <span>Follow along:</span>
          </div>
          <div class="col-sm-6 text-center">
              <a href="https://twitter.com/phalconphp" alt="Twitter" class="btn-social btn-social-twitter"><i class="icon-twitter"></i></a>
              <a href="https://www.facebook.com/pages/Phalcon-Framework/134230726685897" alt="Facebook" class="btn-social btn-social-facebook"><i class="icon-facebook"></i></a>
              <a href="https://plus.google.com/102376109340560896457" alt="Google+" class="btn-social btn-social-googleplus"><i class="icon-googleplus"></i></a>
              <a href="https://github.com/phalcon/cphalcon" alt="Github" class="btn-social btn-social-github"><i class="icon-github"></i></a>
          </div>
          <div class="col-sm-3">
          </div>
      </div>
  </div>

</div>
<footer class="footer">
    <div class="container">
        <div class="row">
            <div class="col-xs-4 col-sm-3">
                <h4>Download</h4>
                <ul>
                    <li><a href="/download">Installing Phalcon PHP</a></li>
                    <li><a href="http://docs.phalconphp.com/en/latest/index.html" class="header-nav-link" target="_blank">Documentation</a></li>
                    <li><a href="http://api.phalconphp.com">API</a></li>
                    <li><a href="http://docs.phalconphp.com/en/latest/reference/tutorial.html">Tutorial</a></li>
                    <li><a href="http://docs.phalconphp.com/en/latest/reference/tutorial.html#sample-applications">Sample Applications</a></li>
                </ul>
            </div>
            <div class="col-xs-4 col-sm-3">
                <h4>Community</h4>
                <ul>
                    <li><a href="http://forum.phalconphp.com/" class="header-nav-link" target="_blank">Forum</a></li>
                    <li><a href="https://github.com/phalcon/cphalcon">GitHub</a></li>
                    <li><a href="https://github.com/phalcon/cphalcon/issues">Issue Tracker</a></li>
                    <li><a href="http://stackoverflow.com/questions/tagged/phalcon">Stack Overflow</a></li>
                    <li><a href="/en/testimonials">Testimonials</a></li>
                    <li><a href="http://builtwith.phalconphp.com/">Built with Phalcon</a></li>
                    <li><a href="http://store.phalconphp.com/">Store</a></li>
                </ul>
            </div>
            <div class="col-xs-4 col-sm-2">
                <h4>About</h4>
                <ul>
                    <li><a class="link-black" href="http://blog.phalconphp.com/">Blog</a></li>
                    <li><a href="/en/about">About</a></li>
                    <li><a href="/en/team">Team</a></li>
                    <li><a href="/en/roadmap">Roadmap</a></li>
                    <li><a href="/en/donate">Donate</a></li>
                    <li><a href="/en/consulting">Consulting</a></li>
                    <li><a href="/en/hosting">Hosting</a></li>
                </ul>
            </div>
            <div id="license-spaccer" class="visible-xs"></div>
            <div id="license-wrapper" class="col-xs-12 col-sm-4">
                <p class="license">
                    Phalcon is an open-source PHP framework <br>built as a C-extension. It is available under the <br>
                    <a href="http://opensource.org/licenses/BSD-3-Clause" target="_blank">new BSD License</a>.
                    <br>
                    <br>
                    Except where otherwise noted, content on this site is licensed under the
                    <a href="http://creativecommons.org/licenses/by/3.0/">Creative Commons Attribution 3.0 License.</a>
                </p>
            </div>
        </div>
    </div>
</footer>

    </div>
    <script type="text/javascript">
    $(window).on("load", function(){
      var cx = '009733439235723428699:lh9ltjgvdz8';
      var gcse = document.createElement('script');
      gcse.type = 'text/javascript';
      gcse.async = true;
      gcse.src = (document.location.protocol == 'https:' ? 'https:' : 'http:') + '//www.google.com/cse/cse.js?cx=' + cx;
      var s = document.getElementsByTagName('script')[0];
      s.parentNode.insertBefore(gcse, s);
    });
    </script>

  </body>
</html>